package com.cn.algorithm02.class04;

import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingDeque;

/***
 * @author: hels
 * @description: 用队列功能实现栈的功能
 **/
public class C06_Queue2Stack {

    public static void main(String[] args) {
        MyStack2 myStack = new MyStack2();
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        System.out.println("aq: " + myStack.aq);
        System.out.println("bq: " + myStack.bq);
        System.out.println("====");
        System.out.println(myStack.pop());
        System.out.println("aq: " + myStack.aq);
        System.out.println("bq: " + myStack.bq);
        System.out.println("====");
        myStack.push(99);
        System.out.println("aq: " + myStack.aq);
        System.out.println("bq: " + myStack.bq);
        System.out.println("peek: " + myStack.peek());
        System.out.println("aq: " + myStack.aq);
        System.out.println("bq: " + myStack.bq);
        System.out.println("====");
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        System.out.println("aq: " + myStack.aq);
        System.out.println("bq: " + myStack.bq);
        System.out.println("====");

    }

    public static class MyStack{
        /*private*/  Queue<Integer> aq = new LinkedBlockingDeque<>();
        /*private*/  Queue<Integer> bq = new LinkedBlockingDeque<>();

        // push
        public void push(Integer i) {
            if(aq.size() > 0 && bq.size() >0) {
                System.out.println("倒腾中...,无法添加");
                return;
            }
            if (bq.size() > 0) {
                bq.add(i);
            } else {
                aq.add(i);
            }
        }

        // pop 弹出元素
        public Integer pop() {
            if(aq.size() > 0 && bq.size() >0) {
                System.out.println("倒腾中...,无法pop");
                return null;
            }

            int size = 0;
            if (bq.size() > 0) {
                size = bq.size();
                for (int i = 0; i < size - 1; i++) {
                    aq.add(bq.poll());
                }
                return bq.poll();
            } else {
                size = aq.size();
                for (int i = 0; i < size - 1; i++) {
                    bq.add(aq.poll());
                }
                return aq.poll();
            }
        }

    }

    // 优化版本
    public static class MyStack2<T>{
        /*private*/  Queue<T> aq ;  // 实际存储数据队列
        private  Queue<T> bq ;

        public MyStack2() {
            aq = new LinkedBlockingDeque<>();
            bq = new LinkedBlockingDeque<>();
        }

        // push
        public void push(T i) {
            if(aq.size() > 0 && bq.size() >0) {
                System.out.println("倒腾中...,无法添加");
                return;
            }
            aq.offer(i);
        }

        // pop 弹出栈顶元素
        public T pop() {
            if(aq.size() > 0 && bq.size() >0) {
                System.out.println("倒腾中...,无法pop");
                return null;
            }

            Queue<T> temp = aq;
            while (aq.size() > 1) {
                bq.offer(aq.poll());
            }
            T ans = aq.poll();
            aq = bq; // 将引用地址做一个替换，方便代码编写
            bq = temp;
            return ans;
        }

        // peek 查询栈顶yuansu
        public T peek() {
            if(aq.size() > 0 && bq.size() >0) {
                System.out.println("倒腾中...,无法pop");
                return null;
            }

            Queue<T> temp = aq;
            while (aq.size() > 1) {
                bq.offer(aq.poll());
            }
            T ans = aq.poll();
            bq.offer(ans);
            aq = bq; // 将引用地址做一个替换，方便代码编写
            bq = temp;
            return ans;
        }

    }
}
